<script setup lang="ts">
import { ref } from 'vue';
const tabValue = ref('Option枚举');

const text = {
  Option枚举: `
    let some_number = Some(5);
    let some_string = Some("你好");

    let absent_number: Option<i32> = None;

    let x: i32 = 5;
    let y: Option<i32> = Some(5);

    // 报错 cannot add Option<i32> to i32
    // 原因 编译器认为 i32 和 Option<i32> 类型不同
    let sum = x + y;

    // 如果 要让 x + y 编译通过，需要将 y 类型改为 i32
    // unwrap() 函数会返回 Option<i32> 中的 i32 值
    let sum = x + y.unwrap();

    println!("Hello, world!{}", sum);
  `,
  '控制流运算符 match': `
    #[derive(Debug)]
    enum UsState {
        Alabama,
        Alaska,
    }

    enum Coin {
        Penny,
        Nickel,
        Dime,
        Quarter(UsState),
    }

    /**
     * 将 枚举变体 变成具体 数字
     */
    fn value_in_cents(coin: Coin) -> u8 {
        match coin {
            Coin::Penny => {
                println!("Lucky penny!");
                1
            }
            Coin::Nickel => 5,
            Coin::Dime => 10,
            Coin::Quarter(state) => {
                println!("Quarter {:?}.", state);
                25
            }
        }
    }

    fn main() {
        /**
         * 控制流运算符 match
         *
         * 允许一个值与一系列模式匹配，执行匹配模式对应的代码
         * 模式可以是字面值、变量、通配符，也可以是包含绑定值的结构体或枚举的字段
         */

        /**
         * 输出 Lucky penny!
         * 输出 1
         */
        println!("{}", value_in_cents(Coin::Penny));

        /**
         * 匹配值模式
         *
         * 匹配的分支可以绑定到被匹配对象的部分值
         * 因此，枚举的每个变体都可以绑定到其值
         */

        /**
         * 输出 State quarter from Alaska.
         * 输出 25
         */
        let c = Coin::Quarter(UsState::Alaska);
        println!("{}", value_in_cents(c));

        /**
         * 匹配 Option<T>
         */

        fn plus_one(x: Option<i32>) -> Option<i32> {
            match x {
                None => None,
                Some(i) => Some(i + 1),
            }
        }

        let five = Some(5);
        let six = plus_one(five);
        let none = plus_one(None);

        /**
         * match 匹配必须穷举所有的可能
         * 但可以使用 _通配符 替代其余没有列出的值
         */

        // u8类型有 256 种可能，但 match 匹配了所有情况
        let v = 0u8;

        match v {
            1 => println!("one"),
            3 => println!("three"),
            5 => println!("five"),
            7 => println!("seven"),
            _ => (),
        }
    }
  `,
  'if let 语句': `
  fn main () {
    /**
     *  if let 语句
     * 
     * 处理只关心一种匹配而忽略其他匹配的情况
     * 更少的代码，更少的缩进，更少的模板代码
     * 放弃了穷举的的可能
     */

    let x = Some(0u8);
    match v {
        Some(3) => {
            println!("three");
        },
        _ => (),
    }
    // or
    if let Some(3) = v {
        println!("three");
    }

    /**
     * 搭配 else 使用
     */
    if let Some(3) = v {
        println!("three")
    } else {
        println!("not three")
    }
  }
  `,
  'Package Crate 定义 Module': `
  fn main () {
    /**
     * Package Crate 定义 Module
     * 
     * Rust 代码组织
     * 1.哪些细节是可以暴露的，哪些细节是私有的
     * 2.作用域内哪些名称有效
     * 
     * 模块系统
     * 1.Package（包）: Cargo的特性，用于构建、测试和共享crate
     * 2.Crate(单元包): 树形结构，可产生一个library或可执行文件
     * 3.Module(模块)、use(使用): 控制代码的组织、作用域、私有路径 
     * 
     * Package 和 Crate
     * 
     * Crate的类型
     * binary(可执行文件)
     * library
     * 
     * Crate Root
     * 源代码文件
     */
  }
  `,
  '路径01': `
  fn main () {
    /**
     * 路径
     * 
     * 路径的两种形式
     * 1.绝对路径 从creat root开始，使用::分隔 使用crate名或字面值 crate
     * 2.相对路径 从当前模块开始，使用::分隔 使用self、super或当前模块的标识符
     * 
     * 标识符之间使用::分隔
     */

    // lib.rs
    mod front_of_house {
        mod hosting {
            fn add_to_waitlist() {}
        }
    }

    pub fn eat_at_restaurant() {
        // 绝对路径
        crate::frount_of_house::hosting::add_to_waitlist();
        // 相对路径
        frount_of_house::hosting::add_to_waitlist();
    }

    // 私有边界
    // 上面代码运行会报错 hosting 是私有模块
    // 默认情况下 模块内的所有东西（模块 函数 方法 枚举 struct enum 常量）都是私有的

    // 将模块设为公有
    pub mod front_of_house {
        pub mod hosting {
            pub fn add_to_waitlist() {}
        }
    }

    // 父级模块无法访问子模块的私有内容
    // 子模块可以使用所有组件模块的内容
  } 
  `,
  '路径02': `
  fn main () {
    /**
     *  super 关键字
     *  用来访问父级模块路径的内容，类似文件系统中的..
     */

    fn serve_order() {}

    mod back_of_house {
        fn fix_incorrent_order() {
            cook_order();
            // 相对路径
            super::serve_order();
            // 绝对路径
            crate::serve_order();
        }
        fn cook_order() {}
    }

    /**
     * pub struct 结构体
     * 
     * pub 放在struct前面，表示结构体公开
     * 但是结构体中的字段默认是私有的，需要使用pub来公开
     */
    pub struct Shoe {
        pub size: u32,
        age: u32,
    }

    mod back_of_house {
        pub struct  Breakfast {
            pub toast: String,
            seasonal_fruit: String,
        }

        impl Breakfast {
            pub fn summer(toast: &str) -> Breakfast {
                Breakfast {
                    toast: String::from(toast),
                    seasonal_fruit: String::from("peaches"),
                }
            }
        }
    }

    pub fn eat_at_restaurant() {
        let mut meal = back_of_house::Breakfast::Breakfast("Rye");
        meal.toast = String::from("Wheat");
        println!("I'd like {} to eat.", meal.toast);
        meal.seasonal_fruit = String::from("blueberries"); // 错误，因为seasonal_fruit是私有的,无法访问
    }

    /**
     * pub enum
     * 
     * enum 是公共的
     * enum 的变体也是公共的
     */
    mod back_of_house {
        pub enum Appetizer {
            Soup,
            Salad,
        }
    }
  } 
  `
};
</script>

<template>
  <t-tabs placement="left" v-model="tabValue">
    <t-tab-panel
      v-for="(value, key) in text"
      :key="key"
      :value="key"
      :label="key"
    >
      <div class="rust_box">
        <h3>{{ key }}</h3>
        <div class="code-view">
          <highlightjs language="rust" :code="value"></highlightjs>
        </div>
      </div>
    </t-tab-panel>
  </t-tabs>
</template>

<style lang="scss" scoped>
.rust_box {
  padding: 24px;
  .code-view {
    border-radius: 8px;
    overflow: hidden;
    overflow-y: auto;
    max-height: calc(100vh - 340px);
    margin-top: 16px;
    // 隐藏滚动条
    &::-webkit-scrollbar {
      display: none;
      width: 0 !important;
      height: 0 !important;
      background: transparent;
      cursor: default;
      -webkit-appearance: none;
    }
  }
}
</style>
